/************************************************************************
 *
 * math_ts.h
 *
 * (c) Copyright 2003-2004 Analog Devices, Inc.  All rights reserved.
 * $Revision: 6 $
 ************************************************************************/

/*
   This include file contains all ADSP 21xxx specific
   Analog extensions to the ANSI include file math.h.

   This file is included by math.h by default.
   To disable the extensions, compile with the option:
        -D__NO_ANSI_EXTENSIONS__
 */

#pragma once
#ifndef __NO_BUILTIN
#pragma system_header /* math_ts.h */
#endif

#ifndef  MATH_TS_H
#define  MATH_TS_H

/* -----------------------------------------------------------------------
    ALOG / ALOG10
   -----------------------------------------------------------------------
         float alogf (float);
         float alog10f (float);

         double alog (double);
         double alog10 (double);

         long double alogd (long double);
         long double alog10d (long double);
   -------------------------------------------------------------------- */

#if defined(__cplusplus)
extern "C" {
#endif

                    _Pragma("linkage_name __alogf")
   float   alogf (float);
                    _Pragma("linkage_name __alog10f")
   float   alog10f (float);

                    _Pragma("linkage_name __alogd")
   long double   alogd (long double);
                    _Pragma("linkage_name __alog10d")
   long double   alog10d (long double);


#ifdef __cplusplus
}   
extern "C++" {

   #pragma always_inline
   __inline  float  alog(float _a)
   {
       return  alogf(_a);
   }
   #pragma always_inline
   __inline  long double  alog(long double _a)
   {
       return  alogd(_a);
   }
   #pragma always_inline
   __inline  double  alog(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  alogf(_a);
#else
       return  alogd(_a);
#endif
   }

   #pragma always_inline
   __inline  float  alog10(float _a)
   {
       return  alog10f(_a);
   }
   #pragma always_inline
   __inline  long double  alog10(long double _a)
   {
       return  alog10d(_a);
   }
   #pragma always_inline
   __inline  double  alog10(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  alog10f(_a);
#else
       return  alog10d(_a);
#endif
   }

}       /* extern "C++" */
#else   /* __cplusplus  */

#ifdef __DOUBLES_ARE_FLOATS__
                    _Pragma("linkage_name __alogf")
   double  alog (double);
                    _Pragma("linkage_name __alog10f")
   double  alog10 (double);
#else
                    _Pragma("linkage_name __alogd")
   double  alog (double);
                    _Pragma("linkage_name __alog10d")
   double  alog10 (double);
#endif

#endif  /* __cplusplus  */


/* -----------------------------------------------------------------------
    COT
   -----------------------------------------------------------------------

         float cotf (float);
         double cot (double);
         long double cotd (long double);

   -------------------------------------------------------------------- */

#if defined(__cplusplus)
extern "C" {
#endif

                    _Pragma("linkage_name __cotf")
   float         cotf (float);

                    _Pragma("linkage_name __cotd")
   long double   cotd (long double);


#ifdef __cplusplus
}
extern "C++" {

   #pragma always_inline
   __inline  float  cot(float _a)
   {
       return  cotf(_a);
   }
   #pragma always_inline
   __inline  long double  cot(long double _a)
   {
       return  cotd(_a);
   }
   #pragma always_inline
   __inline  double  cot(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  cotf(_a);
#else
       return  cotd(_a);
#endif
   }

}       /* extern "C++" */
#else   /* __cplusplus  */

#ifdef __DOUBLES_ARE_FLOATS__
                    _Pragma("linkage_name __cotf")
#else
                    _Pragma("linkage_name __cotd")
#endif
   double  cot(double);

#endif  /* __cplusplus  */


/* -----------------------------------------------------------------------
    ISINF / ISNAN
   -----------------------------------------------------------------------
         int isinff (float);
         int isnanf (float);

         int isinf (double);
         int isnan (double);

         int isinfd (long double);
         int isnand (long double);
   -------------------------------------------------------------------- */

#if defined(__cplusplus)
extern "C" {
#endif

                    _Pragma("linkage_name __isinff")
   int   isinff (float);
                    _Pragma("linkage_name __isnanf")
   int   isnanf (float);

                    _Pragma("linkage_name __isinfd")
   int   isinfd (long double);
                    _Pragma("linkage_name __isnand")
   int   isnand (long double);


#ifdef __cplusplus
}
extern "C++" {

   #pragma always_inline
   __inline  int  isinf(float _a)
   {
       return  isinff(_a);
   } 
   #pragma always_inline
   __inline  int  isinf(long double _a)
   {
       return  isinfd(_a);
   }
   #pragma always_inline
   __inline  int  isinf(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  isinff(_a);
#else
       return  isinfd(_a);
#endif
   }

   #pragma always_inline
   __inline  int  isnan(float _a)
   {
       return  isnanf(_a);
   }
   #pragma always_inline
   __inline  int  isnan(long double _a)
   {
       return  isnand(_a);
   }
   #pragma always_inline
   __inline  int  isnan(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  isnanf(_a);
#else
       return  isnand(_a);
#endif
   }

}       /* extern "C++" */
#else   /* __cplusplus  */


#ifdef __DOUBLES_ARE_FLOATS__
                    _Pragma("linkage_name __isinff")
   int   isinf (double);
                    _Pragma("linkage_name __isnanf")
   int   isnan (double);
#else
                    _Pragma("linkage_name __isinfd")
   int   isinf (double);
                    _Pragma("linkage_name __isnand")
   int   isnan (double);
#endif

#endif  /* __cplusplus  */


/* -----------------------------------------------------------------------

         float favgf (float, float);
         float fclipf (float, float);
         float fmaxf (float, float);
         float fminf (float, float);
         float copysignf (float, float);
         float signf (float, float);

         double favg (double, double);
         double fclip (double, double);
         double fmax (double, double);
         double fmin (double, double);
         double copysign (double, double);
         double sign (double, double);

         long double favgd (long double, long double);
         long double fclipd (long double, long double);
         long double fmaxd (long double, long double);
         long double fmind (long double, long double);
         long double copysignd (long double, long double);
         long double signd (long double, long double);
   -------------------------------------------------------------------- */

/* ========== BUILTIN versions are available for some functions ========== */

#ifdef __cplusplus
extern "C" {
#endif

   #pragma always_inline
   __inline long double  favgd (long double _x, long double _y)
   {
       return ( (_x + _y) / 2.0L );
   }

                    _Pragma("linkage_name __fclipd")
   long double   fclipd (long double, long double);
                    _Pragma("linkage_name __fmaxd")
   long double   fmaxd (long double, long double);
                    _Pragma("linkage_name __fmind")
   long double   fmind (long double, long double);
                    _Pragma("linkage_name __signd")
   long double   signd (long double, long double);
                    _Pragma("linkage_name __signd")
   long double   copysignd (long double, long double);


#if !defined(__DOUBLES_ARE_FLOATS__) && !defined(__cplusplus)

   #pragma always_inline
   __inline double  favg (double _x, double _y)
   {
       return ( (_x + _y) / 2.0 );
   }

                    _Pragma("linkage_name __fclipd")
   double   fclip (double, double);
                    _Pragma("linkage_name __fmaxd")
   double   fmax (double, double);
                    _Pragma("linkage_name __fmind")
   double   fmin (double, double);
                    _Pragma("linkage_name __signd")
   double   sign (double, double);
                    _Pragma("linkage_name __signd")
   double   copysign (double, double);

#endif


#ifndef __NO_BUILTIN   /* Built-ins are defined */
   float   favgf (float, float);
   float   fclipf (float, float);
   float   fmaxf (float, float);
   float   fminf (float, float);
   float   signf (float, float);
   float   copysignf (float, float);

#ifndef __cplusplus
   double  favg (double, double);
   double  fclip (double, double);
   double  fmax (double, double);
   double  fmin (double, double);
   double  sign (double, double);
   double  copysign (double, double);

#ifdef __DOUBLES_ARE_FLOATS__
   #define  favg       favgf
   #define  fclip      fclipf
   #define  fmax       fmaxf
   #define  fmin       fminf
   #define  sign       signf
   #define  copysign   signf
#endif   /* __DOUBLES_ARE_FLOATS__ */
#endif   /* __cplusplus            */

   #define  favgf     __builtin_favgf
   #define  fclipf    __builtin_fclipf
   #define  fmaxf     __builtin_fmaxf
   #define  fminf     __builtin_fminf
   #define  signf     __builtin_copysignf
   #define  copysignf __builtin_copysignf

#else    /* __NO_BUILTIN */

   #pragma always_inline
   __inline float   favgf (float _x, float _y)
   {
       return ( (_x + _y) / 2.0F );
   }

                    _Pragma("linkage_name __fclipf")
   float   fclipf (float, float);
                    _Pragma("linkage_name __fmaxf")
   float   fmaxf (float, float);
                    _Pragma("linkage_name __fminf")
   float   fminf (float, float);
                    _Pragma("linkage_name __signf")
   float   signf (float, float);
                    _Pragma("linkage_name __signf")
   float   copysignf (float, float);

#if !defined(__cplusplus) && defined(__DOUBLES_ARE_FLOATS__)
   #pragma always_inline
   __inline double   favg (double _x, double _y)
   {
       return ( (_x + _y) / 2.0 );
   }

                    _Pragma("linkage_name __fclipf")
   double   fclip (double, double);
                    _Pragma("linkage_name __fmaxf")
   double   fmax (double, double);
                    _Pragma("linkage_name __fminf")
   double   fmin (double, double);
                    _Pragma("linkage_name __signf")
   double   sign (double, double);
                    _Pragma("linkage_name __signf")
   double   copysign (double, double);

#endif   
#endif   /* __NO_BUILTIN */

#ifdef __cplusplus
}        /* extern "C"  */
extern "C++" {

   #pragma always_inline
   __inline  float  favg(float _a, float _b)
   {
       return  favgf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  favg(long double _a, long double _b)
   { 
       return  favgd(_a, _b);
   }
   #pragma always_inline
   __inline  double  favg(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  favgf(_a, _b);
#else
       return  favgd(_a, _b);
#endif
   }

   #pragma always_inline
   __inline  float  fclip(float _a, float _b)
   {
       return  fclipf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  fclip(long double _a, long double _b)
   {
       return  fclipd(_a, _b);
   }
   #pragma always_inline
   __inline  double  fclip(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  fclipf(_a, _b);
#else
       return  fclipd(_a, _b);
#endif
   }

   #pragma always_inline
   __inline  float  fmax(float _a, float _b)
   {
       return  fmaxf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  fmax(long double _a, long double _b)
   {
       return  fmaxd(_a, _b);
   }
   #pragma always_inline
   __inline  double  fmax(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  fmaxf(_a, _b);
#else
       return  fmaxd(_a, _b);
#endif
   }

   #pragma always_inline
   __inline  float  fmin(float _a, float _b)
   {
       return  fminf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  fmin(long double _a, long double _b)
   {
       return  fmind(_a, _b);
   }
   #pragma always_inline
   __inline  double  fmin(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  fminf(_a, _b);
#else
       return  fmind(_a, _b);
#endif
   }

   #pragma always_inline
   __inline  float  sign(float _a, float _b)
   {
       return  signf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  sign(long double _a, long double _b)
   {
       return  signd(_a, _b);
   }
   #pragma always_inline
   __inline  double  sign(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  signf(_a, _b);
#else
       return  signd(_a, _b);
#endif
   }

   #pragma always_inline
   __inline  float  copysign(float _a, float _b)
   {
       return  signf(_a, _b);
   }
   #pragma always_inline
   __inline  long double  copysign(long double _a, long double _b)
   {
       return  signd(_a, _b);
   }
   #pragma always_inline
   __inline  double  copysign(double _a, double _b)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  copysignf(_a, _b);
#else
       return  copysignd(_a, _b);
#endif
   }

}        /* extern "C++" */
#endif   /* __cplusplus  */



/* -----------------------------------------------------------------------
    RSQRT
   -----------------------------------------------------------------------

         float rsqrtf (float);
         double rsqrt (double);
         long double rsqrtd (long double);

   -------------------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif

                    _Pragma("linkage_name __rsqrtf")
   float         rsqrtf (float);

                    _Pragma("linkage_name __rsqrtd")
   long double   rsqrtd (long double);


#ifdef __cplusplus
}
extern "C++" {

   #pragma always_inline
   __inline  float  rsqrt(float _a)
   {
       return  rsqrtf(_a);
   }
   #pragma always_inline
   __inline  long double  rsqrt(long double _a)
   {
       return  rsqrtd(_a);
   }
   #pragma always_inline
   __inline  double  rsqrt(double _a)
   {
#if defined(__DOUBLES_ARE_FLOATS__)
       return  rsqrtf(_a);
#else
       return  rsqrtd(_a);
#endif
   }

}       /* extern "C++" */
#else   /* __cplusplus  */

#ifdef __DOUBLES_ARE_FLOATS__
                    _Pragma("linkage_name __rsqrtf")
#else
                    _Pragma("linkage_name __rsqrtd")
#endif
   double   rsqrt (double);
 
#endif  /* __cplusplus  */


#endif  /* MATH_TS_H */

